import {
  MeshBasicMaterial,
  PerspectiveCamera,
  Scene,
  ShaderMaterial,
  WebGLRenderer,
  Clock,
  Raycaster,
  Vector2
} from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

// interfaces
import { IWord } from '../interfaces/IWord'

import { Basic } from './Basic'
import Sizes from '../Utils/Sizes'
import { Resources } from './Resources'

import Fireworks from './firework'

// earth
import Earth from './Earth'
import Data from './Data'

export default class World {
  public basic: Basic
  public scene: Scene
  public camera: PerspectiveCamera
  public renderer: WebGLRenderer
  public controls: OrbitControls
  public sizes: Sizes
  public material: ShaderMaterial | MeshBasicMaterial
  public resources: Resources
  public option: IWord
  public earth: Earth
  public clock: Clock
  public fireworks

  constructor(option: IWord) {
    /**
     * 加载资源
     */
    this.option = option

    this.basic = new Basic(option.dom)
    this.scene = this.basic.scene
    this.renderer = this.basic.renderer
    this.controls = this.basic.controls
    this.camera = this.basic.camera

    this.sizes = new Sizes({ dom: option.dom })
    // 管理烟花
    this.fireworks = []

    this.sizes.$on('resize', () => {
      this.renderer.setSize(
        Number(this.sizes.viewport.width),
        Number(this.sizes.viewport.height)
      )
      this.camera.aspect =
        Number(this.sizes.viewport.width) / Number(this.sizes.viewport.height)
      this.camera.updateProjectionMatrix()
    })

    this.resources = new Resources(async () => {
      await this.createEarth()

      // window.addEventListener('click', () => {
      //   this.createFireworks()
      // })

      // 开始渲染
      this.render()
    })
  }

  // 设置创建烟花函数
  createFireworks() {
    // let color = `hsl(${Math.floor(Math.random() * 360)},80%,70%)`
    let color = `hsl(60,80%,70%)`
    let position = {
      // x: (Math.random() - 0.5) * 40,
      // z: -Math.random() * 40,
      // y: (Math.random() - 0.5) * 40
      x: (Math.random() - 0.5) * 3,
      y: (Math.random() + 3) * 3,
      z: -55
    }

    // 随机生成颜色和烟花放的位置
    let firework = new Fireworks(color, position)
    firework.addScene(this.scene, this.camera)
    this.fireworks.push(firework)
  }

  /**
   * 渲染函数
   */
  public render() {
    requestAnimationFrame(this.render.bind(this))
    // requestAnimationFrame(this.createFireworks)
    this.createFireworks()
    this.renderer.render(this.scene, this.camera)
    this.controls && this.controls.update()
    this.fireworks.forEach((item, i) => {
      const type = item.update()
      if (type == 'remove') {
        this.fireworks.splice(i, 1)
      }
    })
    this.earth && this.earth.render()
  }

  async createEarth() {
    // 资源加载完成，开始制作地球，注释在new Earth()类型里面
    this.earth = new Earth({
      data: Data,
      dom: this.option.dom,
      textures: this.resources.textures,
      earth: {
        radius: 50,
        rotateSpeed: 0.002,
        isRotation: true
      },
      // 卫星
      satellite: {
        show: true,
        rotateSpeed: -0.01,
        size: 1,
        number: 2
      },
      punctuation: {
        circleColor: 0xfaff72,
        lightColumn: {
          startColor: 0xff0000, // 起点颜色
          endColor: 0xff0000 // 终点颜色
        }
      },
      flyLine: {
        color: 0xf3ae76, // 飞线的颜色
        flyLineColor: 0xff7714, // 飞行线的颜色
        speed: 0.004 // 拖尾飞线的速度
      }
    })
    console.log('log--> this.earth', this.earth)

    // 创建投射光线对象
    const raycaster = new Raycaster()
    // 鼠标的位置对象
    const mouse = new Vector2()

    // 监听鼠标的位置
    window.addEventListener('click', (event) => {
      console.log(event)
      mouse.x = (event.clientX / window.innerWidth) * 2 - 1
      mouse.y = -((event.clientY / window.innerHeight) * 2 - 1)
      raycaster.setFromCamera(mouse, this.camera)
      let result = raycaster.intersectObjects(this.earth.waveMeshArr)
      //   console.log(result);
      if (result.length > 0) {
        var div = document.createElement('div')
        div.innerHTML = `<div class="overlay" style="position: absolute;top: ${
          event.clientY - 10
        }px;left: ${event.clientX + 10}px; background:pink">ccccc</div>`
        document.querySelector('#earth-canvas').appendChild(div)
      }
    })

    this.scene.add(this.earth.group)

    await this.earth.init()

    // 隐藏dom
    // const loading = document.querySelector('#loading')
    // loading.classList.add('out')
  }
}
